import Cesium from '../Ces/Cesium'
import WeVolumeBox from './WeVolumeBox'
import WeDisplayParameter from './WeDisplayParameter'
import Util from '../Core/Util'
import WeUniform from './WeUniform'

class WeVolume {
  private fragmentMain
  private _position
  private _display
  private _dataProvider
  private _rectangle
  private extrudedHeight
  private width
  private height
  private _scaleZ
  private _offsetZ
  private _scratchCartesian3
  private _modelMatrix
  private _grid
  private _volumeBox
  private extraUniform: WeUniform
  constructor(options) {
    this._display = options.display
    this._dataProvider = options.dataProvider
    this._rectangle = options.rectangle
    this.fragmentMain = options.fragmentMain
    this.extraUniform = options.weUniform
    this.extrudedHeight = this._dataProvider.externalData.size.depth

    this._position = options.position
    this.width = options.width
    this.height = options.height

    this._scaleZ = WeDisplayParameter.scaleZ
    this._offsetZ = WeDisplayParameter.offsetZ

    this._scratchCartesian3 = new Cesium.Cartesian3()
    this._modelMatrix = new Cesium.Matrix4()
    this.calculateModelMatrix()
  }

  calculateModelMatrix() {
    const modelMatrix = this._modelMatrix
    const cartesion = Cesium.Cartographic.toCartesian(this._position, undefined, this._scratchCartesian3)

    Cesium.Transforms.eastNorthUpToFixedFrame(cartesion, undefined, modelMatrix)
    Cesium.Matrix4.multiplyByTranslation(modelMatrix, { x: 0.0, y: 0.0, z: this._offsetZ * this._scaleZ }, modelMatrix)
    Cesium.Matrix4.multiplyByScale(modelMatrix, { x: 1.0, y: 1.0, z: this._scaleZ }, modelMatrix)
  }

  set position(value) {
    this._position = value
    this.calculateModelMatrix()
  }

  get rectangle() {
    return this._rectangle
  }
  get scaleZ() {
    return this._scaleZ
  }
  set scaleZ(value) {
    if (this._scaleZ !== value) {
      this._scaleZ = value
      this.calculateModelMatrix()
      if (this._grid) {
        this._grid.scaleZ = value
      }
    }
  }
  get offsetZ() {
    return this._offsetZ
  }
  set offsetZ(value) {
    if (this._offsetZ !== value) {
      this._offsetZ = value
      this.calculateModelMatrix()
    }
  }

  get modelMatrix() {
    return this._modelMatrix
  }

  update(frameState) {
    if (!frameState.passes.render) return

    if (this.scaleZ !== WeDisplayParameter.scaleZ) {
      this.scaleZ = WeDisplayParameter.scaleZ
    }

    if (!Cesium.defined(this._volumeBox)) {
      this._volumeBox = new WeVolumeBox({
        owner: this,
        extrudedHeight: this.extrudedHeight,
        width: this.width,
        height: this.height,
        display: this._display,
        modelMatrix: this._modelMatrix,
        rectangle: this._rectangle,
        fragmentMain: this.fragmentMain,
        extraUniform: this.extraUniform,
      })
    }

    this._volumeBox.update(frameState)
  }

  destroy() {
    this._volumeBox = this._volumeBox && this._volumeBox.destroy()

    return Cesium.destroyObject(this)
  }

  isdestroyed() {
    return false
  }

  static build(options) {
    const { rectangle } = options
    const { width, height } = Util.computeRectangleMeter(rectangle)
    const position = Cesium.Rectangle.center(rectangle)
    return new WeVolume({
      position,
      width,
      height,
      ...options,
    })
  }

}


export default WeVolume
